﻿using System;
using System.Linq;
using System.Web.Http;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Threading;
//using System.Data.Objects;
using In.Api.Dto.Notify;
using In.Api.Dto.Notify.Notification;
using OutDbContext;
using Rmq.Center;
using In.Api.Dto.HisWs;
using User.Api.HttpClients;
using System.Net.Http;
using Common.Logging;
using Newtonsoft.Json;
using User.Api.Helpers;

namespace User.Api.Controllers
{
    /// <summary>
    /// 处理医院HIS发过来通知
    /// </summary>
    public class ApiNotifyController : ApiController
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(BillController));
        [HttpPost]
        [AllowAnonymous]
        public Response4Notification Notification(Request4Notification notification)
        {
            Logger.ErrorFormat("调用扫码,信息：{0}", JsonConvert.SerializeObject(notification));
            var succeed = "0";
            var failedMsg = "";
            var responseInfo = new Response4NotificationSubResponseInfo();
            switch (notification.NotificationType.ToLower())
            {
                //case "1"://停诊
                //    succeed = HandleHaltInfo(notification, out failedMsg);
                //    break;
                //case "2": //缴费
                //    succeed = HandlePayInfo(notification, out failedMsg);
                //    break;
                //case "3"://预约订单变更
                //    succeed = HandleApptInfo(notification, out failedMsg);
                //    break;
                case "6"://生成二维码
                    succeed = HandleBillInfo(notification, out failedMsg, responseInfo);
                    break;
                case "7": // 订单状态
                    succeed = HandleStatusInfo(notification, out failedMsg, responseInfo);
                    break;
                case "8": // 退费
                    succeed = HandleOrderInfo(notification, out failedMsg, responseInfo); 
                    break;
            }
            return new Response4Notification() { ResultCode = succeed, ResultDesc = failedMsg,ResponseInfo = responseInfo };
        }




        /// <summary>
        /// 生成支付二维码
        /// </summary>
        /// <param name="notification"></param>
        /// <param name="failedMsg"></param>
        /// <param name="url"></param>
        /// <returns></returns>
        public string HandleBillInfo(Request4Notification notification, out string failedMsg,Response4NotificationSubResponseInfo responseInfo,int count=0)
        {
            failedMsg = "生成支付二维码链接失败";

            responseInfo.CodeUrl = "";
            var retValue = "1";
            var isExistsOrder = false;

            var orderNo = "";
            var newOrderId = 0;
            var payFee = "0";

            try
            {
                var billInfo = XmlToObject(notification.NotificationInfo, new BillInfo()) as BillInfo;
                var hospitalId = billInfo.HospitalId ?? "";
                //if (string.IsNullOrEmpty(hospitalId))
                //{
                //    hospitalId = billInfo.DeptName.Contains("广园") ? "0042" : "1408";
                //}
                var dmSumFee = billInfo.SumFee.ToDecimalOrDefault();

                #region 是否存在订单
                using (var ctx = new HzfyWeiXinEntities())
                {
                    var billOrder = ctx.BillOrder.FirstOrDefault(x =>
                        x.ClinicNo == billInfo.ClinicNo && x.PrescMoney.Value == dmSumFee && x.PayState == "1");

                    if (billOrder != null)
                    {
                        isExistsOrder = true;
                        orderNo = billOrder.OrderNo;
                        payFee = (billOrder.PrescMoney * 100).ToInt32().ToString();
                    }
                    else
                    {
                        isExistsOrder = false;

                        orderNo = BillController.GenerateNewOrderNo();
                        var orderModel = new BillOrder();

                        orderModel.BkMemberId = null;
                        orderModel.WxUserId = null;
                        orderModel.OrderNo = orderNo;
                        orderModel.PayType = 1;//支付方式 0-JSAPI 1-扫码

                        orderModel.ClinicNo = billInfo.ClinicNo;
                        orderModel.PrescMoney = billInfo.SumFee.ToDecimalOrDefault();
                       
                        orderModel.OrderStatus = 1;
                       
                        orderModel.PayState = "0";
                        orderModel.CreateTime = DateTime.Now;

                        ctx.BillOrder.Add(orderModel);
                        ctx.SaveChanges();

                        newOrderId = orderModel.Id;
                        payFee = (orderModel.PrescMoney * 100).ToInt32().ToString();
                    }
                }
                #endregion

                #region 生成支付二维码链接
                /*
                 * 扫码商户订单号 = SC + BL + orderNo                                 
                 */
                var outTradeNo = "SC"  + orderNo;
                var startTime = DateTime.Now.ToString("yyyyMMddHHmmss");
                var endTime = DateTime.Now.AddMinutes(15).ToString("yyyyMMddHHmmss"); //15分钟内有效       

                //测试一分钱
                // payFee = "1";
                var result = WeixinPayV3Helper.ComposeJsApiParameter("NATIVE", "就诊缴费", outTradeNo,
    payFee, "127.0.0.1", startTime, endTime, "Bill/SCPaySucceed", "");//扫码支付

                if (result.ResultCode != "0")
                {
                    retValue = "1";
                    failedMsg += (":" + result.ResultMsg);
                    responseInfo.CodeUrl = "";
                    Logger.ErrorFormat("{0}NATIVE失败{1}", orderNo, result.ResultMsg);
                    result = WeixinPayV3Helper.ComposeJsApiParameter("NATIVE", "就诊缴费", outTradeNo,
  payFee, "127.0.0.1", startTime, endTime, "Bill/SCPaySucceed", "");//扫码支付 
                    if (result.ResultCode != "0")
                    {
                        retValue = "1";
                        failedMsg += (":" + result.ResultMsg);
                        responseInfo.CodeUrl = "";
                        Logger.ErrorFormat("{0}NATIVE失败{1}", orderNo, result.ResultMsg);
                    }
                    else
                    {
                        retValue = "0";
                        failedMsg = "生成支付二维码链接成功";
                        responseInfo.CodeUrl = result.Parameter;
                        responseInfo.OrderId = outTradeNo;
                    }
                }
                else
                {
                    retValue = "0";
                    failedMsg = "生成支付二维码链接成功";
                    responseInfo.CodeUrl = result.Parameter;
                    responseInfo.OrderId = outTradeNo;
                }

                #endregion
            }
            catch (Exception ex)
            {
                retValue = "1";
                failedMsg += (":" + ex.Message);
                responseInfo.CodeUrl = "";
                Logger.ErrorFormat("{0}NATIVE失败{1}", orderNo, ex.Message);
                if (count == 0)
                    return HandleBillInfo(notification, out failedMsg, responseInfo, 1);
            }
            return retValue;
        }

        /// <summary>
        /// 退款
        /// </summary>
        /// <param name="notification"></param>
        /// <param name="failedMsg"></param>
        /// <returns></returns>
        public string HandleOrderInfo(Request4Notification notification, out string failedMsg,Response4NotificationSubResponseInfo responseInfo)
        {
            failedMsg = "";
            var retVal = "1";
            //var isRefundSucceed = false;

            try
            {
                var payInfo = (OrderInfo)XmlToObject(notification.NotificationInfo, new OrderInfo());
                if (payInfo == null)
                {
                    return retVal;
                }

                var OrderId = payInfo.OrderId.Replace("SC", "");
                BillOrder order = null;
                using (var ctx = new HzfyWeiXinEntities())
                {
                    order = ctx.BillOrder.FirstOrDefault(x => x.OrderNo == OrderId && x.OrderStatus == 8);
                    if (order == null)
                    {
                        failedMsg = "没有查询到符合条件的订单";
                        return retVal;
                    }

                    #region 退款
                    if (order.PrescMoney.Value > 0)
                    {
                        //var msg = "";
                        //var result = AppointService.DoCancelRegisterRefund(order.Id,1,out msg);
                        //isRefundSucceed = result == 0;

                        // RMQ 执行退费操作
                        var refundingProducer = new OrderRefundingUnpickupSucceedProducer();
                        refundingProducer.Publish(new OrderRefundingUnpickupSucceedMsg
                        {
                            OrderType = Rmq.Center.OrderType.扫码支付订单,
                            OrderId = order.Id
                        });
                    }
                    #endregion

                    retVal = "0";
                    failedMsg = order.Remark;
                    responseInfo.Status = "1";//退款成功
                    responseInfo.RefundId = order.WxRefundId;
                    responseInfo.RefundTime = order.RefundTime.ToString();

                }
               
            }
            catch (Exception ex)
            {
                failedMsg = "处理缴费通知异常:" + ex.Message;
                retVal = "1";
            }
            return retVal;
        }

        /// <summary>
        /// 查询状态
        /// </summary>
        /// <param name="notification"></param>
        /// <param name="failedMsg"></param>
        /// <returns></returns>
        public string HandleStatusInfo(Request4Notification notification, out string failedMsg, Response4NotificationSubResponseInfo responseInfo)
        {
            failedMsg = "";
            var retVal = "1";
            //var isRefundSucceed = false;

            try
            {
                var payInfo = (OrderInfo)XmlToObject(notification.NotificationInfo, new OrderInfo());
                if (payInfo == null)
                {
                    return retVal;
                }
                var OrderId = payInfo.OrderId.Replace("SC", "");
                BillOrder order = null;
                using (var ctx = new HzfyWeiXinEntities())
                {
                    order = ctx.BillOrder.FirstOrDefault(x => x.OrderNo == OrderId);
                    if (order == null)
                    {
                        failedMsg = "没有查询到符合条件的订单";
                        return retVal;
                    }
                    if(order.OrderStatus!=8)
                    {
                        retVal = "0";
                        responseInfo.Status = "2";
                        return retVal;
                    }
                    retVal = "0";
                    responseInfo.Status = "1";
                    responseInfo.TransactionId = order.WxTransactionId;
                    responseInfo.TransactionTime = order.PayTime.ToString();
                }

            }
            catch (Exception ex)
            {
                failedMsg = "查询订单状态异常:" + ex.Message;
                retVal = "1";
            }
            return retVal;
        }


        public string ToXml(Object oObject)
        {
            var xmlDoc = new XmlDocument();
            var xmlSerializer = new XmlSerializer(oObject.GetType());
            using (var xmlStream = new MemoryStream())
            {
                xmlSerializer.Serialize(xmlStream, oObject);
                xmlStream.Position = 0;
                xmlDoc.Load(xmlStream);
                return xmlDoc.InnerXml;
            }
        }

        public  Object XmlToObject(string xmlString, Object oObject)
        {
            var oXmlSerializer = new XmlSerializer(oObject.GetType());
            oObject = oXmlSerializer.Deserialize(new StringReader(xmlString));
            return oObject;
        }
        
    }
}
